package com.xbts.screen.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.xbts.common.core.constant.ScreenConstants;
import com.xbts.common.core.enums.ConsumeTypeEnum;
import com.xbts.common.core.enums.DateTypeEnum;
import com.xbts.common.core.enums.WorkshopTypeEnum;
import com.xbts.common.core.utils.DateUtils;
import com.xbts.common.core.utils.StringUtils;
import com.xbts.common.core.utils.bean.BeanUtils;
import com.xbts.common.core.web.domain.BaseHistogramResult;
import com.xbts.common.core.web.domain.BasePieChartResult;
import com.xbts.common.core.web.domain.BaseRankingResult;
import com.xbts.screen.domain.dto.CostDto;
import com.xbts.screen.domain.dto.HistogramDto;
import com.xbts.screen.domain.vo.ScreenConsumeHistogramVO;
import com.xbts.screen.domain.vo.ScreenQualityDetailsVO;
import com.xbts.screen.domain.workshop.dto.CommonQueryDTO;
import com.xbts.screen.domain.workshop.dto.ConsumeMeterDataDTO;
import com.xbts.screen.domain.workshop.vo.ConsumeDetailsVO;
import com.xbts.screen.domain.workshop.vo.ConsumeMeterDataVO;
import com.xbts.screen.mapper.SyntheticScreenMapper;
import com.xbts.screen.service.ISyntheticScreenServer;
import com.xbts.screen.service.IWorkshopCommonService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author : llk
 * @Date: 2023/12/29 15:34
 */
@Service
public class SyntheticScreenServerImpl implements ISyntheticScreenServer {

    @Resource
    private SyntheticScreenMapper syntheticScreenMapper;
    @Resource
    private IWorkshopCommonService workshopCommonService;

    @DS("wecan")
    @Override
    public BaseHistogramResult screenBusinessDetails() {
        return businessDetailsByDateType(DateTypeEnum.MONTH);
    }
    @DS("wecan")
    @Override
    public List<BaseRankingResult> businessRanking(DateTypeEnum dateType) {
        List<String> times = DateUtils.getStartTimeAndEndTimeByDateTypeEnum(dateType);
        List<HistogramDto> dtoList = syntheticScreenMapper.businessRanking(times.get(0), times.get(1));
        Map<String, List<HistogramDto>> map = dtoList.stream().collect(Collectors.groupingBy(HistogramDto::getXAxis));
        if (map != null && map.size() > 0) {
            List<BaseRankingResult> resultList = new ArrayList<>();
            for (Map.Entry<String, List<HistogramDto>> entry : map.entrySet()) {

                BaseRankingResult result = new BaseRankingResult();
                result.setName(entry.getKey());
                result.setValue(String.format("%.2f", entry.getValue().stream().map(HistogramDto::getActual).mapToDouble(Double::valueOf).sum()));
                resultList.add(result);
            }
            resultList.sort((o1, o2) -> {
                double v1 = Double.parseDouble(o1.getValue());
                double v2 = Double.parseDouble(o2.getValue());
                return v2 > v1 ? 1 : -1;
            });
            for (int i = 1; i <= resultList.size(); i++) {
                resultList.get(i - 1).setNumber(i);
            }
            return resultList;
        }
        return null;
    }

    @DS("wecan")
    @Override
    public BaseHistogramResult businessDetailsByDateType(DateTypeEnum dateType) {
        List<String> times = DateUtils.getStartTimeAndEndTimeByDateTypeEnum(dateType);
        List<HistogramDto> dtoList = syntheticScreenMapper.businessDetailsByDateType(times.get(0), times.get(1));
        if(dtoList == null || dtoList.size() == 0){
            return null;
        }
        String target = dtoList.get(0).getTarget();
        BaseHistogramResult result = new BaseHistogramResult(dateType);
        List<String> xAxis = result.getXAxis();
        List<String> targets = result.getTarget();
        List<String> actual = result.getActual();
        for (int i = 0; i < xAxis.size(); i++) {
            String x = xAxis.get(i);
            targets.set(i, String.format("%.2f",Double.parseDouble(target)));
            for (HistogramDto dto : dtoList) {
                if(DateUtils.xAxisEquals(x, dto.getXAxis(), dateType)){
                    targets.set(i, String.format("%.2f",Double.parseDouble(dto.getTarget())));
                    actual.set(i, String.format("%.2f",Double.sum(Double.parseDouble(actual.get(i)), Double.parseDouble(dto.getActual()))));
                }
            }
            if(!dateType.equals(DateTypeEnum.MONTH)){
                if(dateType.equals(DateTypeEnum.DAY)){
                    targets.set(i, String.format("%.2f", Double.parseDouble(target) / targets.size()));
                } else {
                    targets.set(i, String.format("%.2f", (Double.parseDouble(target) / DateUtils.lengthOfMonth()) * 7));
                }

            }
        }
        return result;
    }

    @DS("wecan")
    @Override
    public List<BasePieChartResult> businessStatistics(DateTypeEnum dateType) {
        List<BasePieChartResult> list = new ArrayList<>();
        BasePieChartResult result1 = new BasePieChartResult();
        BasePieChartResult result2 = new BasePieChartResult();
        BasePieChartResult result3 = new BasePieChartResult();
        list.add(result1);
        list.add(result2);
        list.add(result3);
        switch (dateType){
            case DAY:
                // 昨天
                List<String> yesterday = DateUtils.getYesterdayRange();
                List<HistogramDto> day1 = syntheticScreenMapper.businessDetailsByDateType(yesterday.get(0), yesterday.get(1));
                result1.setType("yesterday");
                if(day1 == null || day1.size() == 0){
                    result1.setRatio("0");
                } else {
                    String target = String.format("%.2f", (Double.parseDouble(day1.get(0).getTarget()) / DateUtils.lengthOfMonth()));
                    double sum = day1.stream().map(HistogramDto::getActual).mapToDouble(Double::valueOf).sum();
                    result1.setRatio(String.format("%.2f", sum / Double.parseDouble(target)));
                }
                // 当天
                List<String> today = DateUtils.getTodayRange();
                List<HistogramDto> day2 = syntheticScreenMapper.businessDetailsByDateType(today.get(0), today.get(1));
                result2.setType("today");
                if(day2 == null || day2.size() == 0){
                    result2.setRatio("0");
                } else {
                    String target = String.format("%.2f", (Double.parseDouble(day2.get(0).getTarget()) / DateUtils.lengthOfMonth()));
                    double sum = day2.stream().map(HistogramDto::getActual).mapToDouble(Double::valueOf).sum();
                    result2.setRatio(String.format("%.2f", sum / Double.parseDouble(target)));
                }
                // 近7天
                List<String> last7Days = DateUtils.getLast7DaysRange();
                List<HistogramDto> day3 = syntheticScreenMapper.businessDetailsByDateType(last7Days.get(0), last7Days.get(1));
                result3.setType("last7Days");
                if(day3 == null || day3.size() == 0){
                    result3.setRatio("0");
                } else {
                    String target = String.format("%.2f", (Double.parseDouble(day3.get(0).getTarget()) / DateUtils.lengthOfMonth()) * 7);
                    double sum = day3.stream().map(HistogramDto::getActual).mapToDouble(Double::valueOf).sum();
                    result3.setRatio(String.format("%.2f", sum / Double.parseDouble(target)));
                }
                break;
            case WEEK:
                // 上周
                List<String> lastWeek = DateUtils.getLastWeek();
                List<HistogramDto> week1 = syntheticScreenMapper.businessDetailsByDateType(lastWeek.get(0), lastWeek.get(1));
                result1.setType("lastWeek");
                if(week1 == null || week1.size() == 0){
                    result1.setRatio("0");
                } else {
                    String target = String.format("%.2f", (Double.parseDouble(week1.get(0).getTarget()) / DateUtils.lengthOfMonth()) * 7);
                    double sum = week1.stream().map(HistogramDto::getActual).mapToDouble(Double::valueOf).sum();
                    result1.setRatio(String.format("%.2f", sum / Double.parseDouble(target)));
                }
                // 本周
                List<String> thisWeek = DateUtils.getCurrentWeek();
                List<HistogramDto> week2 = syntheticScreenMapper.businessDetailsByDateType(thisWeek.get(0), thisWeek.get(1));
                result2.setType("thisWeek");
                if(week2 == null || week2.size() == 0){
                    result2.setRatio("0");
                } else {
                    String target = String.format("%.2f", (Double.parseDouble(week2.get(0).getTarget()) / DateUtils.lengthOfMonth()) * 7);
                    double sum = week2.stream().map(HistogramDto::getActual).mapToDouble(Double::valueOf).sum();
                    result2.setRatio(String.format("%.2f", sum / Double.parseDouble(target)));
                }
                // 近4周
                List<String> lastFourWeek = DateUtils.getTheLastFourWeeks();
                List<HistogramDto> week3 = syntheticScreenMapper.businessDetailsByDateType(lastFourWeek.get(0), lastFourWeek.get(1));
                result3.setType("lastFourWeek");
                if(week3 == null || week3.size() == 0){
                    result3.setRatio("0");
                } else {
                    String target = String.format("%.2f", (Double.parseDouble(week3.get(0).getTarget()) / DateUtils.lengthOfMonth()) * 28);
                    double sum = week3.stream().map(HistogramDto::getActual).mapToDouble(Double::valueOf).sum();
                    result3.setRatio(String.format("%.2f", sum / Double.parseDouble(target)));
                }
                break;
            case MONTH:
                // 上月
                List<String> lastMonth = DateUtils.getLastMonth();
                List<HistogramDto> month1 = syntheticScreenMapper.businessDetailsByDateType(lastMonth.get(0), lastMonth.get(1));
                result1.setType("lastMonth");
                if(month1 == null || month1.size() == 0){
                    result1.setRatio("0");
                } else {
                    String target = String.format("%.2f", Double.parseDouble(month1.get(0).getTarget()));
                    double sum = month1.stream().map(HistogramDto::getActual).mapToDouble(Double::valueOf).sum();
                    result1.setRatio(String.format("%.2f", sum / Double.parseDouble(target)));
                }
                // 本月
                List<String> thisMonth = DateUtils.getCurrentMonth();
                List<HistogramDto> month2 = syntheticScreenMapper.businessDetailsByDateType(thisMonth.get(0), thisMonth.get(1));
                result2.setType("thisMonth");
                if(month2 == null || month2.size() == 0){
                    result2.setRatio("0");
                } else {
                    String target = String.format("%.2f", Double.parseDouble(month2.get(0).getTarget()));
                    double sum = month2.stream().map(HistogramDto::getActual).mapToDouble(Double::valueOf).sum();
                    result2.setRatio(String.format("%.2f", sum / Double.parseDouble(target)));
                }
                // 去年同期
                List<String> lastYearMonth = DateUtils.getLastYearMonthRange();
                List<HistogramDto> month3 = syntheticScreenMapper.businessDetailsByDateType(lastYearMonth.get(0), lastYearMonth.get(1));
                result3.setType("lastYearMonth");
                if(month3 == null || month3.size() == 0){
                    result3.setRatio("0");
                } else {
                    String target = String.format("%.2f", Double.parseDouble(month3.get(0).getTarget()));
                    double sum = month3.stream().map(HistogramDto::getActual).mapToDouble(Double::valueOf).sum();
                    result3.setRatio(String.format("%.2f", sum / Double.parseDouble(target)));
                }
                break;
        }
        return list;
    }

    @DS("wecan")
    @Override
    public BaseHistogramResult capacityDetailsByDateType(DateTypeEnum dateType) {
        List<String> time = DateUtils.getCurrentStartTimeAndEndTimeByDateTypeEnum(dateType);
        List<HistogramDto> list = syntheticScreenMapper.capacityDetailsByDateType(time.get(0), time.get(1));
        BaseHistogramResult result = new BaseHistogramResult();
        List<String> valueList = WorkshopTypeEnum.getValueList();
        result.setXAxis(valueList);
        List<String> targets = new ArrayList<>();
        List<String> actuals = new ArrayList<>();
        double target = 0;
        double actual = 0;
        for (int i = 0; i < valueList.size(); i++) {
            String erpValue = WorkshopTypeEnum.getErpValueByValue(valueList.get(i));
            String[] item = erpValue.split(",");
            targets.add("0");
            actuals.add("0");
            for (HistogramDto item1 : list) {
                String xAxis = item1.getXAxis();
                boolean isExist = false;
                for (String s : item) {
                    isExist = xAxis.indexOf(s) > 0;
                    if(isExist){
                        break;
                    }
                }
                if(isExist){
//                    actual += Double.parseDouble(item1.getActual() == null ? "0" : item1.getActual());
                    if(dateType.equals(DateTypeEnum.MONTH)){
                        target = Double.parseDouble(item1.getTemp() == null ? "0" : item1.getTemp());
                        targets.set(i, String.format("%.2f", Double.parseDouble(item1.getTemp() == null ? "0" : item1.getTemp())));
                    } else if(dateType.equals(DateTypeEnum.WEEK)){
                        target = Double.parseDouble(item1.getTarget() == null ? "0" : item1.getTarget()) * 6;
                        targets.set(i, String.format("%.2f", Double.parseDouble(item1.getTarget() == null ? "0" : item1.getTemp()) * 6));
                    } else {
                        target = Double.parseDouble(item1.getTarget() == null ? "0" : item1.getTarget());
                        targets.set(i, String.format("%.2f", Double.parseDouble(item1.getTarget() == null ? "0" : item1.getTarget())));
                    }
                    actuals.set(i, String.format("%.2f", Double.parseDouble(item1.getActual() == null ? "0" : item1.getActual())));
                    if(WorkshopTypeEnum.PACKAGING.getValue().equals(valueList.get(i))){
                        actual = Double.parseDouble(item1.getActual() == null ? "0" : item1.getActual());
                    }
                    break;
                }
            }
        }
//        targets.set(0, String.format("%.2f", target * (valueList.size() - 1)));
        for (int i = 0; i < targets.size(); i++) {
            targets.set(i, String.format("%.2f", target));
        }
        actuals.set(0, String.format("%.2f", actual));
        result.setTarget(targets);
        result.setActual(actuals);
        return result;
    }

    @DS("wecan")
    @Override
    public BaseHistogramResult capacityWorkshopDetailsByDateType(DateTypeEnum dateType, String value) {
        BaseHistogramResult result = new BaseHistogramResult(dateType);

        List<List<String>> list = DateUtils.getDateListByDateTypeEnum(dateType);
        String target = "0";
        for (int i = 0; i < list.size(); i++) {
            List<String> times = list.get(i);
            List<HistogramDto> histogramDtos = syntheticScreenMapper.capacityWorkshopDetailsByDateType(times.get(0), times.get(1), WorkshopTypeEnum.getErpValueByValue(value));

            if(histogramDtos != null && histogramDtos.size() > 0){
                HistogramDto histogramDto = histogramDtos.get(0);
                if (histogramDtos.size() > 1) {
                    histogramDto.setActual(String.format("%.2f", histogramDtos.stream().mapToDouble(v -> Double.parseDouble(v.getActual())).sum()));
                }
                if(dateType.equals(DateTypeEnum.MONTH)){
                    result.getTarget().set(i, String.format("%.2f", Double.parseDouble(histogramDto.getTemp() == null ? "0" : histogramDto.getTemp())));
                } else if (dateType.equals(DateTypeEnum.WEEK)){
                    result.getTarget().set(i, String.format("%.2f", Double.parseDouble(histogramDto.getTarget() == null ? "0" : histogramDto.getTarget()) * 6));
                } else {
                    result.getTarget().set(i, String.format("%.2f", Double.parseDouble(histogramDto.getTarget() == null ? "0" : histogramDto.getTarget())));
                }
                target = result.getTarget().get(i);
                result.getActual().set(i, String.format("%.2f", Double.parseDouble(histogramDto.getActual() == null ? "0" : histogramDto.getActual())));
            }
        }
        List<String> targetList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            targetList.add(target);
        }
        result.setTarget(targetList);
        return result;
    }
    @DS("wecan")
    @Override
    public List<BaseHistogramResult> consumeOverallDetailsByDateType(DateTypeEnum dateType) {
        List<String> time = DateUtils.getCurrentStartTimeAndEndTimeByDateTypeEnum(dateType);
        List<BaseHistogramResult> resultList = new ArrayList<>();
        // 良品率
        BaseHistogramResult passRate = new BaseHistogramResult();
        resultList.add(passRate);
        // 报废率
        BaseHistogramResult scrapRate = new BaseHistogramResult();
        resultList.add(scrapRate);
        // 客诉率
        BaseHistogramResult complaintRate = new BaseHistogramResult();
        resultList.add(complaintRate);
        List<String> valueList = WorkshopTypeEnum.getValueList();
        List<String> targetList = new ArrayList<>();
        List<String> passRateList = new ArrayList<>();
        List<String> scrapRateList = new ArrayList<>();
        List<String> complaintRateList = new ArrayList<>();
        passRate.setXAxis(valueList);
        passRate.setTarget(targetList);
        passRate.setActual(passRateList);
        scrapRate.setXAxis(valueList);
        scrapRate.setTarget(targetList);
        scrapRate.setActual(scrapRateList);
        complaintRate.setXAxis(valueList);
        complaintRate.setTarget(targetList);
        complaintRate.setActual(complaintRateList);
        List<HistogramDto> dtoList = syntheticScreenMapper.getPassRateAndScrapRate(time.get(0), time.get(1), null);
        for (String s : valueList) {
            // TODO 报废率  合格率  客诉率  暂无目标值
            targetList.add("50");
            List<HistogramDto> temp = dtoList.stream().filter(v -> v.getXAxis().contains(s)).collect(Collectors.toList());
            if(temp.size() > 0){
                scrapRateList.add(String.format("%.2f", temp.stream().map(HistogramDto::getTarget).mapToDouble(Double::valueOf).sum() / temp.size()));
                passRateList.add(String.format("%.2f", temp.stream().map(HistogramDto::getActual).mapToDouble(Double::valueOf).sum() / temp.size()));
            } else {
                passRateList.add("0");
                scrapRateList.add("0");
            }
            // 客诉率
            List<HistogramDto> list = syntheticScreenMapper.getComplaintRate(time.get(0), time.get(1), WorkshopTypeEnum.getErpValueByValue(s));
            if(temp.size() > 0 && list != null && list.size() > 0){
                complaintRateList.add(list.stream().map(HistogramDto::getActual).mapToInt(Integer::valueOf).sum() + "");
            } else {
                complaintRateList.add("0");
            }
        }

        // 计算总体
        passRateList.set(0, String.format("%.2f", passRateList.stream().mapToDouble(Double::valueOf).sum() / passRateList.size()));
        scrapRateList.set(0, String.format("%.2f", scrapRateList.stream().mapToDouble(Double::valueOf).sum() / scrapRateList.size()));
        complaintRateList.set(0, String.format("%.2f", complaintRateList.stream().mapToDouble(Double::valueOf).sum() / complaintRateList.size()));

        return resultList;
    }
    @DS("wecan")
    @Override
    public List<BaseHistogramResult> qualityWorkshopOverallDetailsByDateType(DateTypeEnum dateType) {
        return qualityWorkshopDetailsByDateType(dateType, null);
    }
    @DS("wecan")
    @Override
    public List<BaseHistogramResult> qualityWorkshopDetailsByDateType(DateTypeEnum dateType, String value) {
        List<String> time = DateUtils.getStartTimeAndEndTimeByDateTypeEnum(dateType);
        BaseHistogramResult passRate = new BaseHistogramResult(),scrapRate = new BaseHistogramResult(),complaintRate = new BaseHistogramResult();
        List<BaseHistogramResult> resultList = Arrays.asList(passRate,scrapRate,complaintRate);
        List<String> valueList = DateUtils.getXAxisByDateTypeEnum(dateType);
        List<String> targetList = new ArrayList<>();
        List<String> passRateList = new ArrayList<>();
        List<String> scrapRateList = new ArrayList<>();
        List<String> complaintRateList = new ArrayList<>();

        List<HistogramDto> dtoList = syntheticScreenMapper.getPassRateAndScrapRate(time.get(0), time.get(1), value);
        // 客诉率
        List<HistogramDto> list = syntheticScreenMapper.getComplaintRate(time.get(0), time.get(1), value);
        for (String s : valueList) {
            // TODO 报废率  合格率  客诉率  暂无目标值
            targetList.add("50");
            List<HistogramDto> xAxisEquals = dtoList.stream().filter(v -> DateUtils.xAxisEquals(s, v.getTemp(), dateType)).collect(Collectors.toList());
            List<HistogramDto> xAxisEquals2 = list.stream().filter(v -> DateUtils.xAxisEquals(s, v.getTemp(), dateType)).collect(Collectors.toList());
            if(xAxisEquals.size() > 0){
                scrapRateList.add(String.format("%.2f", xAxisEquals.stream().map(HistogramDto::getTarget).mapToDouble(Double::valueOf).sum() / xAxisEquals.size()));
                passRateList.add(String.format("%.2f", xAxisEquals.stream().map(HistogramDto::getActual).mapToDouble(Double::valueOf).sum() / xAxisEquals.size()));
            } else {
                passRateList.add("0");
                scrapRateList.add("0");
            }
            if(xAxisEquals.size() > 0 && xAxisEquals2.size() > 0){
                complaintRateList.add(xAxisEquals2.stream().map(HistogramDto::getActual).mapToInt(Integer::valueOf).sum() + "");
            } else {
                complaintRateList.add("0");
            }
        }
        passRate.setXAxis(valueList);
        passRate.setTarget(targetList);
        passRate.setActual(passRateList);
        scrapRate.setXAxis(valueList);
        scrapRate.setTarget(targetList);
        scrapRate.setActual(scrapRateList);
        complaintRate.setXAxis(valueList);
        complaintRate.setTarget(targetList);
        complaintRate.setActual(complaintRateList);
        return resultList;
    }
    @DS("wecan")
    @Override
    public Map<String, Object> qualityWorkshopContributeByDateType(DateTypeEnum dateType, String value) {

        List<String> time = DateUtils.getCurrentStartTimeAndEndTimeByDateTypeEnum(dateType);
        CommonQueryDTO dto = new CommonQueryDTO();
        dto.setStartTime(time.get(0));
        dto.setEndTime(time.get(1));
        dto.setDeptNames(Arrays.asList(WorkshopTypeEnum.getErpValueByValue(value).split(",")));
        List<BasePieChartResult> scrapResults = workshopCommonService.scrapStatistics(dto);
        List<BasePieChartResult> badResults = workshopCommonService.badStatistics(dto);
        Map<String, Object> map = new HashMap<>();
        map.put("scrapStatistics", scrapResults);
        map.put("badStatistics", badResults);
        map.put("complaintRate", null);
        return map;
    }

    @DS("wecan")
    @Override
    public BaseHistogramResult screenCapacityDetails() {
        List<List<String>> timeList = DateUtils.getDateListByDateTypeEnum(DateTypeEnum.MONTH);
        List<String> target = new ArrayList<>();
        List<String> actual = new ArrayList<>();
        for (int i = 6; i < timeList.size(); i++) {
            List<String> time = timeList.get(i);
            List<HistogramDto> list = syntheticScreenMapper.capacityDetailsByDateType(time.get(0), time.get(1));
            if(list.size() > 0){
                target.add(String.format("%.2f", list.stream().map(HistogramDto::getTemp).mapToDouble(Double::valueOf).sum()));
                actual.add(String.format("%.2f", list.stream().map(HistogramDto::getActual).mapToDouble(Double::valueOf).sum()));
            }else{
                target.add("0");
                actual.add("0");
            }
        }
        BaseHistogramResult result = new BaseHistogramResult();
        result.setXAxis(DateUtils.getLastTwelveMonths().subList(6, 12));
        result.setTarget(target);
        result.setActual(actual);

        return result;
    }

    @DS("wecan")
    @Override
    public List<ScreenQualityDetailsVO> screenQualityDetails() {
        ScreenQualityDetailsVO month = new ScreenQualityDetailsVO(), week = new ScreenQualityDetailsVO(), day = new ScreenQualityDetailsVO();
        List<ScreenQualityDetailsVO> vos = Arrays.asList(month, week, day);
        // 月
        List<String> lastMonth = DateUtils.getLastMonth();
        List<HistogramDto> lastMonthComplaintRate = syntheticScreenMapper.getComplaintRate(lastMonth.get(0), lastMonth.get(1), null);
        List<String> currentMonth = DateUtils.getCurrentMonth();
        List<HistogramDto> currentMonthComplaintRate = syntheticScreenMapper.getComplaintRate(currentMonth.get(0), currentMonth.get(1), null);
        month.setTarget("150");
        month.setLastTime(lastMonthComplaintRate.size() <= 0 ? "0" : lastMonthComplaintRate.stream().map(HistogramDto::getActual).mapToInt(Integer::valueOf).sum() + "");
        month.setThisTime(currentMonthComplaintRate.size() <= 0 ? "0" : currentMonthComplaintRate.stream().map(HistogramDto::getActual).mapToInt(Integer::valueOf).sum() + "");
        // 周
        List<String> lastWeek = DateUtils.getLastWeek();
        List<HistogramDto> lastWeekComplaintRate = syntheticScreenMapper.getComplaintRate(lastWeek.get(0), lastWeek.get(1), null);
        List<String> currentWeek = DateUtils.getCurrentWeek();
        List<HistogramDto> currentWeekComplaintRate = syntheticScreenMapper.getComplaintRate(currentWeek.get(0), currentWeek.get(1), null);
        week.setTarget("40");
        week.setLastTime(lastWeekComplaintRate.size() <= 0 ? "0" : lastWeekComplaintRate.stream().map(HistogramDto::getActual).mapToInt(Integer::valueOf).sum() + "");
        week.setThisTime(currentWeekComplaintRate.size() <= 0 ? "0" : currentWeekComplaintRate.stream().map(HistogramDto::getActual).mapToInt(Integer::valueOf).sum() + "");
        // 日
        List<String> yesterday = DateUtils.getYesterdayDate();
        List<HistogramDto> yesterdayComplaintRate = syntheticScreenMapper.getComplaintRate(yesterday.get(0), yesterday.get(1), null);
        List<String> today = DateUtils.getTodayDate();
        List<HistogramDto> todayComplaintRate = syntheticScreenMapper.getComplaintRate(today.get(0), today.get(1), null);
        day.setTarget("5");
        day.setLastTime(yesterdayComplaintRate.size() <= 0 ? "0" : yesterdayComplaintRate.stream().map(HistogramDto::getActual).mapToInt(Integer::valueOf).sum() + "");
        day.setThisTime(todayComplaintRate.size() <= 0 ? "0" : todayComplaintRate.stream().map(HistogramDto::getActual).mapToInt(Integer::valueOf).sum() + "");
        return vos;
    }

    @DS("wecan")
    @Override
    public BaseHistogramResult screenQualityAnalyseA() {
        List<List<String>> timeList = DateUtils.getDateListByDateTypeEnum(DateTypeEnum.MONTH);
        List<String> target = new ArrayList<>();
        List<String> actual = new ArrayList<>();
        for (int i = 6; i < timeList.size(); i++) {
            target.add("95");
            List<String> time = timeList.get(i);
            List<HistogramDto> dtoList = syntheticScreenMapper.getPassRateAndScrapRate(time.get(0), time.get(1), null);
            List<HistogramDto> temp = dtoList.stream().filter(v -> {
                for (String s : WorkshopTypeEnum.getErpValueList()) {
                    if (s.contains(v.getXAxis()) && v.getActual() != null) {
                        return true;
                    }
                }
                return false;
            }).collect(Collectors.toList());
            actual.add(temp.size() <= 0 ? "100" : String.format("%.2f", temp.stream().map(HistogramDto::getActual).mapToDouble(Double::valueOf).sum() / temp.size()));
        }
        BaseHistogramResult result = new BaseHistogramResult();
        List<String> lastSixMonths = DateUtils.getLastSixMonths();
        result.setXAxis(lastSixMonths);
        result.setTarget(target);
        result.setActual(actual);
        return result;
    }

    @DS("wecan")
    @Override
    public BaseHistogramResult screenQualityAnalyseB() {
        BaseHistogramResult result = new BaseHistogramResult();
        List<String> xAxis = new ArrayList<>();
        List<String> target = new ArrayList<>();
        List<String> actual = new ArrayList<>();
        result.setXAxis(xAxis);
        result.setTarget(target);
        result.setActual(actual);
        // 月
        BaseHistogramResult month = screenQualityAnalyseA();
        xAxis.addAll(month.getXAxis().subList(3, 6));
        target.addAll(month.getTarget().subList(3, 6));
        actual.addAll(month.getActual().subList(3, 6));

        // 周
        List<List<String>> timeList = DateUtils.getDateListByDateTypeEnum(DateTypeEnum.WEEK);
        for (int i = 4; i < timeList.size(); i++) {
            target.add("95");
            List<String> time = timeList.get(i);
            List<HistogramDto> dtoList = syntheticScreenMapper.getPassRateAndScrapRate(time.get(0), time.get(1), null);
            List<HistogramDto> temp = dtoList.stream().filter(v -> {
                for (String s : WorkshopTypeEnum.getErpValueList()) {
                    if (s.contains(v.getXAxis()) && v.getActual() != null) {
                        return true;
                    }
                }
                return false;
            }).collect(Collectors.toList());
            actual.add(temp.size() <= 0 ? "100" : String.format("%.2f", temp.stream().map(HistogramDto::getActual).mapToDouble(Double::valueOf).sum() / temp.size()));
        }
        xAxis.addAll(DateUtils.getLastEightWeeks().subList(4, 8));
        // 天
        timeList = DateUtils.Last7DaysRange();
        for (int i = 0; i < timeList.size(); i++) {
            target.add("95");
            List<String> time = timeList.get(i);
            List<HistogramDto> dtoList = syntheticScreenMapper.getPassRateAndScrapRate(time.get(0), time.get(1), null);
            List<HistogramDto> temp = dtoList.stream().filter(v -> {
                for (String s : WorkshopTypeEnum.getErpValueList()) {
                    if (s.contains(v.getXAxis()) && v.getActual() != null) {
                        return true;
                    }
                }
                return false;
            }).collect(Collectors.toList());
            actual.add(temp.size() <= 0 ? "100" : String.format("%.2f", temp.stream().map(HistogramDto::getActual).mapToDouble(Double::valueOf).sum() / temp.size()));
        }
        xAxis.addAll(DateUtils.getLastTenDays().subList(3, 10));
        return result;
    }

    @DS("wecan")
    @Override
    public List<BasePieChartResult> screenCostDetailsA(List<String> time) {
        if (time == null || time.size() == 0) {
            time = DateUtils.getStartTimeAndEndTimeByDateTypeEnum(DateTypeEnum.MONTH);
        }
        List<BasePieChartResult> results = new ArrayList<>();
        // 人力
        BasePieChartResult manpower = new BasePieChartResult();
        manpower.setType(ConsumeTypeEnum.MANPOWER.name());
        manpower.setLabel(ConsumeTypeEnum.MANPOWER.getValue());
        manpower.setValue("0");
        List<CostDto> manpowerCost = getCostDtoList(time, ConsumeTypeEnum.MANPOWER, null);
        if(manpowerCost.size() > 0){
            manpower.setValue(String.format("%.2f", manpowerCost.stream().map(CostDto::getAmount).mapToDouble(Double::valueOf).sum() / 10000));
        }
        results.add(manpower);
        // 水
        BasePieChartResult water = new BasePieChartResult();
        water.setType(ConsumeTypeEnum.WATER.name());
        water.setLabel(ConsumeTypeEnum.WATER.getValue());
        water.setValue("0");
        List<CostDto> waterCost = getCostDtoList(time, ConsumeTypeEnum.WATER, null);
        if(waterCost.size() > 0) {
            water.setValue(String.format("%.2f", waterCost.stream().map(CostDto::getAmount).mapToDouble(Double::valueOf).sum() / 10000));
        }
        results.add(water);
        // 电
        BasePieChartResult electricity = new BasePieChartResult();
        electricity.setType(ConsumeTypeEnum.ELECTRICITY.name());
        electricity.setLabel(ConsumeTypeEnum.ELECTRICITY.getValue());
        electricity.setValue("0");
        List<CostDto> electricityCost = getCostDtoList(time, ConsumeTypeEnum.ELECTRICITY, null);
        if(waterCost.size() > 0) {
            electricity.setValue(String.format("%.2f", electricityCost.stream().map(CostDto::getAmount).mapToDouble(Double::valueOf).sum() / 10000));
        }
        results.add(electricity);
        // 材料
        BasePieChartResult material = new BasePieChartResult();
        material.setType(ConsumeTypeEnum.MATERIAL.name());
        material.setLabel(ConsumeTypeEnum.MATERIAL.getValue());
        material.setValue("0");
        List<CostDto> materialCost = getCostDtoList(time, ConsumeTypeEnum.MATERIAL, null);
        if(materialCost.size() > 0) {
            material.setValue(String.format("%.2f", materialCost.stream().map(CostDto::getAmount).mapToDouble(Double::valueOf).sum() / 10000));
        }
        results.add(material);
        // 其他
        BasePieChartResult other = new BasePieChartResult();
        other.setType(ConsumeTypeEnum.OTHER.name());
        other.setLabel(ConsumeTypeEnum.OTHER.getValue());
        other.setValue("0");
        List<CostDto> otherCost = getCostDtoList(time, ConsumeTypeEnum.OTHER, null);
        if(waterCost.size() > 0) {
            other.setValue(String.format("%.2f", otherCost.stream().map(CostDto::getAmount).mapToDouble(Double::valueOf).sum() / 10000));
        }
        results.add(other);
        return results;
    }

    @DS("wecan")
    @Override
    public BaseHistogramResult screenCostDetailsB(DateTypeEnum dateTypeEnum) {
        if (dateTypeEnum == null) {
            dateTypeEnum = DateTypeEnum.MONTH;
        }
        BaseHistogramResult result = new BaseHistogramResult(dateTypeEnum);
        List<List<String>> timeList = DateUtils.getDateListByDateTypeEnum(dateTypeEnum);
        for (int i = 0; i < timeList.size(); i++) {
            List<String> time = timeList.get(i);
            List<BasePieChartResult> dtoList = screenCostDetailsA(time);
            result.getTarget().set(i, "200");
            if(dtoList.size() > 0){
                result.getActual().set(i, String.format("%.2f", dtoList.stream().map(BasePieChartResult::getValue).mapToDouble(Double::valueOf).sum()));
            }
        }
        return result;
    }

    @DS("wecan")
    @Override
    public BaseHistogramResult costOverallDetailsByDateType(DateTypeEnum dateType) {

        switch (dateType){
            case WEEK:
                return screenCostDetailsB(DateTypeEnum.WEEK);
            case MONTH:
                return screenCostDetailsB(DateTypeEnum.MONTH);
            default:
                return screenCostDetailsB(DateTypeEnum.DAY);
        }
    }

    @DS("wecan")
    @Override
    public BaseHistogramResult costWorkshopOverallDetailsByDateTypeAndConsumeType(DateTypeEnum dateType, ConsumeTypeEnum consumeType) {
        BaseHistogramResult result = new BaseHistogramResult();
        DateUtils.getDateListByDateTypeEnum(dateType);
        List<String> valueList = WorkshopTypeEnum.getValueList();
        result.setXAxis(valueList.subList(1, valueList.size()));
        List<String> targetList = new ArrayList<>();
        List<String> actualList = new ArrayList<>();
        result.setTarget(targetList);
        result.setActual(actualList);

        List<String> erpValueList = WorkshopTypeEnum.getErpValueList();
        List<String> time = DateUtils.getCurrentStartTimeAndEndTimeByDateTypeEnum(dateType);
        for (int i = 1; i < erpValueList.size(); i++) {
            String deptName = erpValueList.get(i);
            List<CostDto> dtoList = getCostDtoList(time, consumeType, deptName);
            result.getTarget().add(dateType.equals(DateTypeEnum.MONTH) ? "50000" : dateType.equals(DateTypeEnum.WEEK) ? "18000" : "4000");
            result.getActual().add("0");
            if(dtoList.size() > 0){
                result.getActual().set(i - 1, String.format("%.2f", dtoList.stream().map(CostDto::getAmount).mapToDouble(Double::valueOf).sum()));
            }
        }
        return result;
    }

    @DS("wecan")
    @Override
    public BaseHistogramResult costWorkshopDetailsByDateTypeAndConsumeType(DateTypeEnum dateType, ConsumeTypeEnum consumeType, String value) {
        BaseHistogramResult result = new BaseHistogramResult(dateType);
        List<List<String>> timeList = DateUtils.getDateListByDateTypeEnum(dateType);
        for (int i = 0; i < timeList.size(); i++) {
            List<String> time = timeList.get(i);
            List<CostDto> dtoList = getCostDtoList(time, consumeType, value);
            result.getTarget().set(i, "50000");
            if(dtoList.size() > 0){
                result.getActual().set(i, String.format("%.2f", dtoList.stream().map(CostDto::getAmount).mapToDouble(Double::valueOf).sum()));
            }
        }
        return result;
    }

    @DS("wecan")
    @Override
    public ScreenConsumeHistogramVO screenConsumeDetails() {
        ScreenConsumeHistogramVO vo = new ScreenConsumeHistogramVO();
        List<String> xAxis = new ArrayList<>();
        List<String> waterTargets = new ArrayList<>();
        List<String> waterActuals = new ArrayList<>();
        List<String> electricityTargets = new ArrayList<>();
        List<String> electricityActuals = new ArrayList<>();
        vo.setXAxis(xAxis);
        vo.setWaterTarget(waterTargets);
        vo.setWaterActual(waterActuals);
        vo.setElectricityTarget(electricityTargets);
        vo.setElectricityActual(electricityActuals);

        double produceArea = 0;
        List<List<String>> lists = DateUtils.Last10DaysRange();
        CommonQueryDTO dto = new CommonQueryDTO();
        List<String> range = DateUtils.getLast30DaysRange();
        dto.setStartTime(range.get(0));
        dto.setEndTime(range.get(1));
        List<ConsumeDetailsVO> allVos = workshopCommonService.consumeDetailsByDateType(dto);
        Map<String, ConsumeDetailsVO> allMap = new HashMap<>();
        for (ConsumeDetailsVO allVo : allVos) {
            allMap.put(allVo.getWorkshopName(), allVo);
        }
        dto.setDeptNames(Arrays.asList(WorkshopTypeEnum.PACKAGING.getErpValue().split(",")));
        for (List<String> time : lists) {
            String s = time.get(0);
            Date date = DateUtils.parseDate(s);
            xAxis.add(DateUtils.parseDateToStr("MM/dd", date));
            dto.setStartTime(time.get(0));
            dto.setEndTime(time.get(1));
            List<ConsumeDetailsVO> vos = workshopCommonService.consumeDetailsByDateType(dto);
            if(vos != null && vos.size() > 0){
                produceArea = vos.stream().map(ConsumeDetailsVO::getProduceArea).mapToDouble(Double::valueOf).sum();
            }

            ConsumeMeterDataDTO dataDTO = new ConsumeMeterDataDTO();
            List<String> erpValueList = WorkshopTypeEnum.getErpValueList();
            double electricityValue = 0;
            double electricityTarget = 0;
            double waterValue = 0;
            double waterTarget = 0;
            for (String erpValue : erpValueList) {
                dataDTO.setStartTime(time.get(0));
                dataDTO.setEndTime(time.get(1));
                dataDTO.setDeptNames(Arrays.asList(erpValue.split(",")));
                dataDTO.setMeterType(ScreenConstants.ELECTRICITY_METER);
                Map<String, String> electricityTotal = workshopCommonService.totalConsume(dataDTO);
                electricityValue += Double.parseDouble(electricityTotal.get("value"));
//                electricityTarget += Double.parseDouble(electricityTotal.get("target"));
                if(allMap.containsKey(erpValue)){
                    electricityTarget += Double.parseDouble(allMap.get(erpValue).getElectricityTarget());
                    waterTarget += Double.parseDouble(allMap.get(erpValue).getWaterTarget());
                }

                dataDTO.setMeterType(ScreenConstants.WATER_METER);
                Map<String, String> waterTotal = workshopCommonService.totalConsume(dataDTO);
                waterValue += Double.parseDouble(waterTotal.get("value"));
//                waterTarget += Double.parseDouble(waterTotal.get("target"));

            }
            waterTargets.add(String.format("%.2f", waterTarget));
            waterActuals.add(String.format("%.2f", waterValue > 0 ? waterValue / produceArea : 0));
            electricityTargets.add(String.format("%.2f", electricityTarget));
            electricityActuals.add(String.format("%.2f", electricityValue > 0 ? electricityValue / produceArea : 0));

        }
        return vo;
    }

    @Override
    public BaseHistogramResult consumeDetailsByDateType(DateTypeEnum dateType, ConsumeTypeEnum consumeType) {
        BaseHistogramResult result = new BaseHistogramResult();
        result.setXAxis(WorkshopTypeEnum.getValueList().subList(1, WorkshopTypeEnum.getValueList().size()));
        List<String> target = new ArrayList<>();
        List<String> actual = new ArrayList<>();
        result.setActual(actual);
        result.setTarget(target);
        List<String> time = DateUtils.getCurrentStartTimeAndEndTimeByDateTypeEnum(dateType);
        List<String> pastTime = DateUtils.getPastTimeByDateTypeEnum(dateType);
        CommonQueryDTO dto = new CommonQueryDTO();
        dto.setStartTime(time.get(0));
        dto.setEndTime(time.get(1));
        ConsumeMeterDataDTO dataDTO = new ConsumeMeterDataDTO();
        for (String deptName : WorkshopTypeEnum.getErpValueList()) {
            if(StringUtils.isBlank(deptName)) continue;
            dto.setDeptNames(Arrays.asList(deptName.split(",")));
            dataDTO.setDeptNames(Arrays.asList(deptName.split(",")));
            List<ConsumeDetailsVO> vos = workshopCommonService.consumeDetailsByDateType(dto);
            List<String> last30DaysRange = DateUtils.getLast30DaysRange();
            dto.setStartTime(last30DaysRange.get(0));
            dto.setEndTime(last30DaysRange.get(1));
            List<ConsumeDetailsVO> last30DaysRangeVos = workshopCommonService.consumeDetailsByDateType(dto);
            if(last30DaysRangeVos.size() <= 0) {
                target.add("0");
                actual.add("0");
                continue;
            } else {
                if(ConsumeTypeEnum.ELECTRICITY.equals(consumeType)){
                    target.add(last30DaysRangeVos.get(0).getElectricityTarget());
                } else {
                    target.add(last30DaysRangeVos.get(0).getWaterTarget());
                }
            }
            if(vos.size() <= 0) {
                actual.add("0");
                continue;
            }
            if(ConsumeTypeEnum.ELECTRICITY.equals(consumeType)){
                target.add(vos.get(0).getElectricityTarget());
                dataDTO.setMeterType(ScreenConstants.ELECTRICITY_METER);
            } else {
                target.add(vos.get(0).getWaterTarget());
                dataDTO.setMeterType(ScreenConstants.WATER_METER);
            }
            // 总生产面积
            double sum = vos.stream().map(ConsumeDetailsVO::getProduceArea).mapToDouble(Double::valueOf).sum();
            if(sum <= 0) {
                actual.add("0");
            }
            // 获取当前读数
            dataDTO.setStartTime(time.get(0));
            dataDTO.setEndTime(time.get(1));
            List<ConsumeMeterDataVO> dataVOS = workshopCommonService.getConsumeMeterData(dataDTO);
            double latestReading = 0;
            if(dataVOS.size() > 0) {
                latestReading = dataVOS.get(0).getReading();
                latestReading = latestReading > 0 ? latestReading : 0;

            // 获取历史最高读数
            dataDTO.setStartTime(pastTime.get(0));
            dataDTO.setEndTime(pastTime.get(1));
            double originalReading = 0;
            List<ConsumeMeterDataVO> originalVOS = workshopCommonService.getConsumeMeterData(dataDTO);
            if(originalVOS.size() > 0) {
                originalReading = originalVOS.get(0).getReading();
                originalReading = originalReading > 0 ? originalReading : 0;
            }
            double use = latestReading - originalReading;
            actual.add(String.format("%.2f", use / sum));
            } else {
                actual.add("0");
            }
        }
        return result;
    }

    @Override
    public BaseHistogramResult consumeWorkshopDetailsByDateType(DateTypeEnum dateType, ConsumeTypeEnum consumeType, String deptName) {
        // 产能数据
        BaseHistogramResult result = new BaseHistogramResult(dateType);

        List<String> time = DateUtils.getStartTimeAndEndTimeByDateTypeEnum(dateType);
        CommonQueryDTO dto = new CommonQueryDTO();
        dto.setStartTime(time.get(0));
        dto.setEndTime(time.get(1));
        dto.setDeptNames(Arrays.asList(WorkshopTypeEnum.getErpValueByValue(deptName).split(",")));
        ConsumeMeterDataDTO dataDTO = new ConsumeMeterDataDTO();
        dataDTO.setDeptNames(Arrays.asList(WorkshopTypeEnum.getErpValueByValue(deptName).split(",")));

        List<ConsumeDetailsVO> vos = workshopCommonService.consumeDetailsByDateType(dto);
        if(vos.size() <= 0) return result;
        List<String> target = new ArrayList<>();
        List<String> actual = new ArrayList<>();
        result.setTarget(target);
        result.setActual(actual);
        String targetData;
        if(ConsumeTypeEnum.ELECTRICITY.equals(consumeType)){
            targetData = vos.get(0).getElectricityTarget();
            dataDTO.setMeterType(ScreenConstants.ELECTRICITY_METER);
        } else {
            targetData = vos.get(0).getWaterTarget();
            dataDTO.setMeterType(ScreenConstants.WATER_METER);
        }

        List<List<String>> timeList = DateUtils.getDateListByDateTypeEnum(dateType);
        for (int i = 0; i < timeList.size(); i++) {
            List<String> times = timeList.get(i);
            target.add(targetData);
            List<ConsumeDetailsVO> consumeDetailsVOs = vos.stream().filter(vo -> DateUtils.isDateInRange(vo.getTime(), times.get(0), times.get(1))).collect(Collectors.toList());
            if(consumeDetailsVOs != null && consumeDetailsVOs.size() > 0) {
                dataDTO.setStartTime(times.get(0));
                dataDTO.setEndTime(times.get(1));
                // 获取当前读数
                List<ConsumeMeterDataVO> dataVOS = workshopCommonService.getConsumeMeterData(dataDTO);
                double latestReading = 0;
                if (dataVOS.size() > 0) {
                    latestReading = dataVOS.get(0).getReading();
                    latestReading = latestReading > 0 ? latestReading : 0;
                    List<String> pastTime = DateUtils.getPastTimeByTime(times.get(0));
                    // 获取历史最高读数
                    dataDTO.setStartTime(pastTime.get(0));
                    dataDTO.setEndTime(pastTime.get(1));
                    double originalReading = 0;
                    List<ConsumeMeterDataVO> originalVOS = workshopCommonService.getConsumeMeterData(dataDTO);
                    if (originalVOS.size() > 0) {
                        originalReading = originalVOS.get(0).getReading();
                        originalReading = originalReading > 0 ? originalReading : 0;
                    }
                    double use = latestReading - originalReading;
                    actual.add(String.format("%.2f", use / consumeDetailsVOs.stream().map(ConsumeDetailsVO::getProduceArea).mapToDouble(Double::valueOf).sum()));
                } else {
                    actual.add("0");
                }
            } else {
                actual.add("0");
            }
        }

        return result;
    }

    private List<CostDto> getCostDtoList(List<String> time, ConsumeTypeEnum consumeType, String deptName) {
        List<CostDto> costDtoList;
        switch (consumeType) {
            case WATER:
                costDtoList = syntheticScreenMapper.getWaterCost(time.get(0), time.get(1), deptName);
                break;
            case ELECTRICITY:
                costDtoList = syntheticScreenMapper.getElectricityCost(time.get(0), time.get(1), deptName);
                break;
            case MANPOWER:
                costDtoList = syntheticScreenMapper.getManpowerCost(time.get(0), time.get(1), deptName);
                break;
            case MATERIAL:
                costDtoList = syntheticScreenMapper.getMaterialCost(time.get(0), time.get(1), deptName);
                break;
            default:
                costDtoList = syntheticScreenMapper.getOtherCost(time.get(0), time.get(1), deptName);
                break;
        }
        return costDtoList;
    }

}